console.inspectEnable = true;
import WebApp from 'webapp';
const app = WebApp.createApp();
const bodyParser = require('middleware').bodyParser;
app.use(bodyParser.json());
app.use(WebApp.static('./public'));
import devManager from './libs/device_manager';
import { dataDB } from './data/lkv_db';
import { initSocketIO } from './libs/socket_server';
import { IKeyValue, IUser } from './interfaces/common.interface';
import { ICallBack, ICreateRoomData, IResponse, IRoomRealValue } from './interfaces/api.interface';
import { ILogInfo, IManager, IRoom } from './interfaces/lkv.interface';
import { IDeviceType, ISimpleDevice } from './interfaces/device.interface';
import { WAIT_HANDLE_PERIOD } from './data/const';
import utils from './libs/utils';
import Log from './libs/log';

let times = {}; // 设备实时值获取定时器
let roomTimes = {}; // 关闭房间所有设备的延时定时器
let roomRealValues: IRoomRealValue = {}; // 房间设备实时数据
let room_list: IRoom[] = (dataDB.get('rooms') as IRoom[]) || []; // 房间
let manager_list: IManager[] = (dataDB.get('managers') as IManager[]) || []; // 管理员
const logManager = new Log(); // 日志持久化管理

// room_list = room_list.map((item) => {
//   item.count = 0
//   return item
// })
// updateRooms()

/* 应用启动时，初始化房间实时值和房间运行状态 */
initRoomRealValue();

// ================== Socket.IO Server =====================
const io = initSocketIO(app);
io.sockets.on('connection', (socket) => {
  /* 初始化管理员信息，这里如果说持久化数据中没有存储管理员信心，
     说明应用是第一次打开，这时候就默认当前登录的用户为超级管理员 */
  socket.on('init-manager', (accountInfo: IUser, cb: ICallBack) => {
    if (utils.isObject(accountInfo) && accountInfo.acoid) {
      try {
        /* 应用初次启动时，默认设备设备密码为超级管理员 */
        if (!manager_list.length) {
          manager_list.push({ ...accountInfo, super: true });
          dataDB.set('managers', manager_list);
        }
        const index = manager_list.findIndex((item: IManager) => {
          return item.acoid === accountInfo.acoid;
        });
        if (index >= 0) {
          cb({ result: true, message: '欢迎您，尊贵的管理员【' + accountInfo.nickname + '】!' });
        }
      } catch (error) {
        cb({ result: false, message: '应用数据初始化失败！' });
      }
    } else {
      cb({ result: false, message: '参数错误！' });
    }
  });

  /* 应用初始化、数据同步 */
  socket.on('init', () => {
    emitRoomMessage(socket.id, 'rooms', room_list || []);
    emitRoomMessage(socket.id, 'devices', [...devManager.devMap.values()]);
    emitRoomMessage(socket.id, 'managers', manager_list || []);
  });

  socket.on('start-rooms', (cb) => {
    // 开启所有房间
    let controllerError = false;
    room_list.map((room: IRoom, index: number) => {
      if (!room.status) {
        room.status = true;
        // 实例化房间内所有设备的控制对象
        room.devids.map((devid: string, idx: number) => {
          const dev = devManager.devMap.get(devid);
          if (dev) {
            generateDevController(devid, room.id)
              .then(null, () => {
                controllerError = true;
              })
              .finally(() => {
                if (index === room_list.length - 1 && idx === room.devids.length - 1 && controllerError) {
                  emitMessage('error', '部分房间设备初始化异常！');
                }
              });
          }
        });
      }
      return room;
    });
    updateRooms();
    cb({ result: true, message: '操作成功' });
  });

  /* 创建房间 */
  socket.on('create-room', (data: ICreateRoomData, cb: ICallBack) => {
    const { creator, name } = data;
    if (utils.isObject(creator) && creator.acoid && name.trim()) {
      const sameNameRoom = room_list.find((room) => {
        return room.name === name.trim();
      });
      if (sameNameRoom) {
        /* 房间同名 */
        return cb({ result: false, message: '房间名已存在，请修改名称后再试！' });
      }
      let id = generateRoomId();
      // 创建房间对应数据库表
      logManager.createTable(id, (res: IResponse) => {
        if (!res.result) {
          cb({ result: false, message: '操作失败，请重试！' });
        } else {
          const room: IRoom = {
            id,
            name: name.trim(),
            creator,
            create_time: utils.formatDate(new Date()),
            devids: [],
            status: false,
            settings: {
              illu: 30,
              ac_cp: ['00:00', '23:59'],
              light_cp: ['00:00', '23:59']
            },
            count: 0
          };
          room_list.push(room);
          updateRooms();
          // 新建房间初始化实时值
          roomRealValues[room.id] = {
            illuSensor: [],
            bodySensor: [],
            ac: []
          };
          cb({ result: true, message: '房间创建成功！', data: room });
        }
      });
    } else {
      cb({ result: false, message: '参数错误！' });
    }
  });

  /* 删除房间 */
  socket.on('delete-room', (room_id: string, cb: ICallBack) => {
    if (room_id) {
      logManager.deleteTable(room_id, 3, (res: IResponse) => {
        if (!res.result) {
          cb({ result: false, message: '删除房间操作失败，请重试！' });
        } else {
          room_list = room_list.filter((item: IRoom) => {
            return item.id !== room_id;
          });
          delete roomRealValues[room_id];
          updateRooms();
          cb({ result: true, message: '删除房间成功！' });
        }
      });
    } else {
      cb({ result: false, message: '参数错误，请刷新页面重试！' });
    }
  });

  /* 进入房间、初始化房间数据 */
  socket.on('init-room', (room_id: string, cb) => {
    if (!room_id) {
      return cb({ result: false, message: '参数房间id为空，请刷新页面重试！' });
    }
    const room = room_list.find((item) => {
      return item.id === room_id;
    });
    if (!room) {
      cb({ result: false, message: '未找到对应的房间！' });
    } else {
      if (!room.status) {
        // 说明应用打开从未进入过房间，此时房间所有设备处于停止运行状态
        room_list = room_list.map((item) => {
          if (item.id === room.id) {
            item.status = true;
          }
          return item;
        });
        updateRooms();
      }
      /* 这里必须在房间设备for of循环之前， 因为客户端在收到join事件之前需要获取到当前房间信息 */
      cb({ result: true, message: '房间数据同步成功！', data: room });
      /* 构建房间设备控制对象 */
      for (const devid of room.devids) {
        const dev = devManager.devMap.get(devid);
        if (!dev) continue;
        if (!devManager.controllerMap.has(devid)) {
          generateDevController(devid, room_id).then(
            // 因为设备是共用的，所以说全局emit消息
            () => {
              emitMessage('join', { ...dev, status: true }); // status 为 true 代表设备控制对象构建完成，运行正常
            },
            () => {
              devManager.controllerMap.set(devid, null);
              emitMessage('join', { ...dev, status: false }); // status 为 false 代表设备控制对象构建失败，运行异常
            }
          );
        } else {
          initDevCurrentValue(dev);
          emitMessage('join', { ...dev, status: true });
        }
      }
    }
  });

  /* 添加房间设备 */
  socket.on('add-device', ({ room_id, devid }, cb) => {
    if (!room_id || !devid) {
      return cb({ result: false, message: '参数错误！' });
    }
    const dev = devManager.devMap.get(devid);
    if (!dev) {
      return cb({ result: false, message: '设备信息未找到，请刷新重试！' });
    }
    generateDevController(devid, room_id).then(
      () => {
        room_list = room_list.map((item) => {
          if (item.id === room_id) {
            // 是否在房间内
            const isExistDevid = item.devids.find((id) => {
              return id === devid;
            });
            if (!isExistDevid) {
              item.devids.push(devid);
              // 记录添加日志
              const dev = devManager.devMap.get(devid);
              if (dev) {
                saveLog(room_id, `设备【${dev.alias}】被加入房间！`, 'success');
              }
            }
          }
          return item;
        });
        updateRooms();
        emitMessage('add', { room_id, dev: { ...dev, status: true } });
        cb({ result: true, message: '添加设备成功！' });
      },
      () => {
        cb({ retult: false, message: `操作出错或应用缺少控制设备的权限！` });
      }
    );
  });

  /* 删除房间设备 */
  socket.on('delete-device', ({ room_id, devid }, cb) => {
    if (!room_id || !devid) {
      return cb({ result: false, message: '参数错误！' });
    }
    let clear = true; // 是否清除该设备的定时器
    room_list = room_list.map((item) => {
      if (item.id === room_id) {
        // 如果为当前房间删除指定的设备id
        item.devids = item.devids.filter((item) => {
          return item !== devid;
        });
      } else {
        // 如果不是当前房间,则检查是否存在该设备，如果存在则不能清除该设备的控制对象
        if (item.devids.includes(devid)) {
          clear = false;
        }
      }
      return item;
    });
    updateRooms();
    if (clear) {
      clearInterval(times[devid]);
      times[devid] = undefined;
    }
    cb({ result: true, message: '删除设备成功！' });
    emitMessage('delete', { room_id, dev: devManager.devMap.get(devid) });
    // 记录日志
    const dev = devManager.devMap.get(devid);
    if (dev) {
      saveLog(room_id, `设备【${dev.alias}】被删除！`, 'warning');
    }
  });

  /* 发送设备消息 */
  socket.on('send-device-message', (devid, data: IKeyValue, cb) => {
    devManager.sendDeviceInfo(devid, data).then(
      () => {
        cb({ result: true, message: '操作成功！' });
      },
      () => {
        cb({ result: false, message: '设备控制消息发送失败，请重试！' });
      }
    );
  });

  /* 改变房间设置 */
  socket.on('change-room-setting', ({ room_id, data: { illu, ac_control_period, light_control_period, name } }, cb) => {
    let success = false;
    room_list.map((room) => {
      if (room.id === room_id) {
        room.name = name;
        room.settings.illu = Number(illu);
        room.settings.ac_cp = ac_control_period;
        room.settings.light_cp = light_control_period;
        success = true;
      }
      return room;
    });
    if (success) {
      updateRooms();
      cb({ result: true, message: '设置成功！' });
    } else {
      cb({ result: false, message: '设置失败, 未找到对应的房间信息，请退出重试!' });
    }
  });

  /* 切换房间所有设备 */
  socket.on('switch-room-devices', ({ room_id, status }, cb) => {
    const room = room_list.find((item) => item.id === room_id);
    if (!room) {
      cb({ result: false, message: '操作失败，找不到当前房间信息，请退出重试!' });
    } else {
      // 通过当前的光照值判断是否开灯状态
      let lightStatus = false;
      const curRoomRealValue = roomRealValues[room_id];
      if (curRoomRealValue) {
        for (const item of curRoomRealValue.illuSensor) {
          if (item.value > room.settings.illu) {
            lightStatus = true;
            break;
          }
        }
      }
      if (status) {
        // 打开所有关闭的设备
        room.devids.map((devid) => {
          const dev = devManager.devMap.get(devid);
          if (dev) {
            switch (dev.type) {
              case 'ac-control':
                devManager.sendDeviceInfo(devid, { method: 'set', ac: 'ON' });
                break;
              case 'light-control':
                if (!lightStatus) {
                  devManager.sendDeviceInfo(devid, { method: 'set', SW_ctrl: 'ON' });
                }
                break;
              case 'light-ac-control':
                devManager.sendDeviceInfo(devid, { method: 'set', ac: 'ON' });
                if (!lightStatus) {
                  devManager.sendDeviceInfo(devid, { method: 'set', SW_ctrl: 'ON' });
                }
                break;
              default:
                break;
            }
          }
        });
      } else {
        // 关闭所有打开的设备
        room.devids.map((devid) => {
          const dev = devManager.devMap.get(devid);
          if (dev) {
            switch (dev.type) {
              case 'ac-control':
                devManager.sendDeviceInfo(devid, { method: 'set', ac: 'OFF' });
                break;
              case 'light-control':
                if (lightStatus) {
                  devManager.sendDeviceInfo(devid, { method: 'set', SW_ctrl: 'OFF' });
                }
                break;
              case 'light-ac-control':
                devManager.sendDeviceInfo(devid, { method: 'set', ac: 'OFF' });
                if (lightStatus) {
                  devManager.sendDeviceInfo(devid, { method: 'set', SW_ctrl: 'OFF' });
                }
                break;
              default:
                break;
            }
          }
        });
      }
      cb({ result: true, message: '操作成功!' });
    }
  });

  /* 获取当前房间操作日志 */
  socket.on('log', ({ room_id, date }, cb) => {
    if (!room_id || !date) {
      return cb({ result: false, message: '获取日志信息出错, 请退出重试！' });
    }
    logManager.queryTableContentByDate(room_id, date, 200, (res) => {
      cb(res);
    });
  });

  /* 添加管理员 */
  socket.on('add-manager', (data: IUser, cb) => {
    const sameAcoid = manager_list.find((item) => item.acoid === data.acoid);
    if (sameAcoid) {
      return cb({ result: false, message: '当前用户acoid已存在！' });
    }
    const sameName = manager_list.find((item) => item.acoid === data.acoid);
    if (sameName) {
      return cb({ result: false, message: '当前用户名已存在！' });
    }
    manager_list.unshift(data);
    dataDB.set('managers', manager_list);
    emitMessage('managers', manager_list);
    cb({ result: true, message: '新增管理员成功！' });
  });

  /* 删除管理员(只有超管才能删除) */
  socket.on('delete-manager', (acoid, cb) => {
    manager_list = manager_list.filter((item) => {
      return item.acoid !== acoid;
    });
    dataDB.set('managers', manager_list);
    emitMessage('managers', manager_list);
    cb({ result: true, message: '删除管理员成功！' });
  });
});

devManager.on('join', (dev) => {
  if (!dev) {
    return emitMessage('error', '页面设备信息出错，请退出重试！');
  }
  emitMessage('devices', [...devManager.devMap.values()]);
  const room = room_list.find((item) => {
    return item.devids.includes(dev.devid);
  });
  if (room) {
    saveLog(room.id, `设备【${dev.alias}】上线！`, 'success');
    generateDevController(dev.devid, room.id).then(
      () => {
        saveLog(room.id, `获取设备【${dev.alias}】控制权成功！`, 'success');
        emitMessage('join', { ...dev, status: true });
      },
      () => {
        saveLog(room.id, `获取设备【${dev.alias}】控制权失败！`, 'error');
        devManager.controllerMap.set(dev.devid, null);
        emitMessage('join', { ...dev, status: false });
      }
    );
  }
});

devManager.on('lost', (dev) => {
  if (!dev) {
    return emitMessage('error', '页面设备信息出错，请退出重试！');
  }
  emitMessage('devices', [...devManager.devMap.values()]);
  clearInterval(times[dev.devid]);
  // times[dev.devid] = undefined;
  emitMessage('lost', { ...dev, status: false });
  const room = room_list.find((item) => {
    return item.devids.includes(dev.devid);
  });
  if (room) {
    saveLog(room.id, `设备【${dev.alias}】掉线！`, 'warning');
  }
});

devManager.on('error', (data) => {
  emitMessage('error', data);
});

// 构建设备控制对象
function generateDevController(devid: string, room_id: string) {
  return new Promise((resolve, reject) => {
    devManager.generateController(devid).then(
      (controller) => {
        const dev = devManager.devMap.get(devid);
        controller.on('message', (data: IKeyValue) => {
          const room = room_list.find((item) => item.id === room_id);
          if (!room) {
            return;
            // emitMessage('error', '页面与设备消息通信中断，请退出重试！');
          }
          /* 向前端同步的数据（因为复合设备的存在，所以这里额外添加了type字段以作区分复合设备中的单设备 */
          let value: undefined | { devid: string; value: any; type: IDeviceType; c_type?: IDeviceType } = undefined;
          switch (dev.type) {
            case 'body-sensor':
            case 'body-illu-sensor':
              if (data.data && data.data['micro_state'] !== undefined) {
                console.log('receive message from body sensor: ', JSON.stringify(data));
                // 单人体传感器和复合设备中的人体传感器
                value = { devid, type: dev.type, c_type: 'body-sensor', value: data.data['micro_state'] };
                // 存储实时值
                updateCacheRealValue(room.id, 'bodySensor', devid, data.data['micro_state']);
                // 判断当前所有人体感应设备的状态
                let existPeople = false;
                for (const item of roomRealValues[room.id]['bodySensor']) {
                  if (item.value === 'ON') {
                    existPeople = true;
                    clearTimeout(roomTimes[`ac-${room_id}`]);
                    clearTimeout(roomTimes[`light-${room_id}`]);
                    roomTimes[`ac-${room_id}`] = undefined;
                    roomTimes[`light-${room_id}`] = undefined;
                    break;
                  }
                }
                console.log('exist people: ', existPeople);
                if (!existPeople) {
                  // 控制空调和灯光
                  if (dev && roomTimes[`ac-${room_id}`] === undefined && roomTimes[`light-${room_id}`] === undefined) {
                    let enableCount = false; // 是否本次记录生效次数
                    // 添加定时器处理，比操作生效延迟半分钟
                    const t = setTimeout(() => {
                      if (enableCount) {
                        addRoomAutoControlCount(room_id);
                      } else {
                        clearTimeout(t);
                      }
                    }, (WAIT_HANDLE_PERIOD + 0.5) * 60 * 1000);
                    const { ac_devids, light_devids } = getRoomOnlineCtlDevids(room);
                    console.log(
                      'ready to close Device number: light:' + light_devids.length + ', ac:' + ac_devids.length
                    );
                    if (ac_devids.length) {
                      const inTimeRange = checkControlTimeRange(room, 'ac');
                      if (inTimeRange) {
                        roomTimes[`ac-${room_id}`] = setTimeout(() => {
                          // 获取当前在线的所有空调设备
                          const { ac_devids } = getRoomOnlineCtlDevids(room);
                          console.info('start close AC Device number: ' + ac_devids.length);
                          // 获取当前在线并且开启的空调设备
                          const acArr = roomRealValues[room_id]['ac'].filter((item) => {
                            return item.value === 'ON' && ac_devids.includes(item.devid);
                          });
                          if (acArr.length) {
                            saveLog(room_id, `长时间检测无人，已自动关闭房间空调！`, 'success');
                            enableCount = true;
                            acArr.forEach((item) => {
                              devManager.sendDeviceInfo(item.id, { method: 'set', ac: 'OFF' });
                            });
                          }
                        }, WAIT_HANDLE_PERIOD * 60 * 1000);
                      }
                    }
                    if (light_devids.length) {
                      const inTimeRange = checkControlTimeRange(room, 'light');
                      if (inTimeRange) {
                        roomTimes[`light-${room_id}`] = setTimeout(() => {
                          // 取光照传感器的最高数据
                          const maxIlluValue = Math.max(
                            ...roomRealValues[room_id]['illuSensor'].map((item) => {
                              return item.value;
                            })
                          );
                          if (maxIlluValue > room.settings.illu) {
                            // 获取当前在线的所有灯光设备
                            const { light_devids } = getRoomOnlineCtlDevids(room);
                            console.info('start close Light Device number: ' + light_devids.length);
                            if (light_devids.length) {
                              enableCount = true;
                              saveLog(room_id, `长时间检测无人，已自动关闭房间灯光！`, 'success');
                              light_devids.forEach((id) => {
                                devManager.sendDeviceInfo(id, { method: 'set', SW_ctrl: 'OFF' });
                              });
                            }
                          }
                        }, WAIT_HANDLE_PERIOD * 60 * 1000);
                      }
                    }
                  }
                }
                // 状态存入日志中
                // if (data.method === 'report') {
                //   saveLog(room_id, `房间【${room.name}】中检测${existPeople ? '有' : '没'}人！`);
                // }
              }
              // 复合设备中的光照传感器
              if (data.data && data.data['illu'] !== undefined && typeof data.data['illu'] === 'number') {
                // 复合设备中的光照传感器
                value = { devid, type: dev.type, c_type: 'illu-sensor', value: parseInt(data.data['illu'].toString()) };
                updateCacheRealValue(room.id, 'illuSensor', devid, parseInt(data.data['illu'].toString()));
              }
              break;
            case 'illu-sensor':
              if (data.data && typeof data.data['illu'] === 'number') {
                value = { devid, type: dev.type, value: parseInt(data.data['illu'].toString()) };
                updateCacheRealValue(room.id, 'illuSensor', devid, parseInt(data.data['illu'].toString()));
              }
              break;
            case 'ac-control':
            case 'light-ac-control': // 这里复合设备light-ac-control中只有空调控制会给应用发送消息
              if (data.data && data.data['ac']) {
                // 更新空调实时状态
                updateCacheRealValue(room.id, 'ac', devid, data.data['ac']);
                // 空调控制
                value = { devid, type: dev.type, c_type: 'ac-control', value: data.data['ac'] };
                if (data.method === 'report') {
                  // 保存操作日志
                  saveLog(room_id, `空调${data.data['ac'] === 'ON' ? '开启' : '关闭'}`, 'success');
                }
              }
              break;
            default:
              break;
          }
          if (value !== undefined) {
            // io.sockets.emit('message', value);
            emitMessage('message', value)
          }
        });

        if (dev.type === 'illu-sensor') {
          clearInterval(times[devid]);
          times[devid] = setInterval(() => {
            devManager.sendDeviceInfo(devid, { method: 'get', obj: ['illu'] });
          }, 3 * 1000);
        } else if (dev.type === 'body-sensor') {
          clearInterval(times[devid]);
          times[devid] = setInterval(() => {
            devManager.sendDeviceInfo(devid, { method: 'get', obj: ['micro_state'] });
          }, 2 * 60 * 1000);
        } else if (dev.type === 'body-illu-sensor') {
          clearInterval(times[devid]);
          times[devid] = setInterval(() => {
            devManager.sendDeviceInfo(devid, { method: 'get', obj: ['illu', 'micro_state'] });
          }, 3 * 1000);
        }

        initDevCurrentValue(dev);
        resolve(controller);
      },
      (error) => {
        reject(`no permission.`);
        throw new Error('[generateController]: ' + error);
      }
    );
  });
}

/* 更新房间传感器最新数据 */
function updateCacheRealValue(
  room_id: string,
  type: 'illuSensor' | 'bodySensor' | 'ac',
  devid: string,
  value: number | string
) {
  let flag = false;
  // 存入实时数据
  roomRealValues[room_id][type] = roomRealValues[room_id]['illuSensor'].map((item) => {
    if (item.devid === devid) {
      flag = true;
      item.value = value;
    }
    return item;
  });
  if (!flag) {
    roomRealValues[room_id][type].push({
      devid: devid,
      value: value
    });
  }
}

/**
 * 检测当前是否在控制时间范围内
 * @param room 房间
 * @param type 类型
 * @returns 状态
 */
function checkControlTimeRange(room: IRoom, type: 'light' | 'ac') {
  const {
    settings: { ac_cp, light_cp }
  } = room || {};
  let range = [];
  if (type === 'ac') {
    range = ac_cp;
  } else if (type === 'light') {
    range = light_cp;
  } else {
    return;
  }
  const date = new Date();
  const curTimeMinute = date.getHours() * 60 + date.getMinutes();
  const start_times = range[0].split(':');
  const end_times = range[1].split(':');
  const start_time_minute = Number(start_times[0]) * 60 + Number(start_times[1]);
  const end_time_minute = Number(end_times[0]) * 60 + Number(end_times[1]);
  if (start_time_minute <= end_time_minute) {
    // 如果开始时间小于等于结束时间，说明没有跨越次日零点
    // 取开始时间-结束时间之间
    if (curTimeMinute >= start_time_minute && curTimeMinute < end_time_minute) {
      // 添加定时器延时
      return true;
    }
  } else {
    // 如果开始时间大于结束时间，说明跨越了次日零点
    // 去开始时间-23:59 和 00:00-结束时间
    if (curTimeMinute > start_time_minute || curTimeMinute < end_time_minute) {
      // 添加定时器延时
      return true;
    }
  }
  return false;
}

/* 更新房间信息 */
function updateRooms() {
  try {
    dataDB.begin();
    dataDB.set('rooms', room_list);
    dataDB.commit();
    emitMessage('rooms', room_list);
  } catch (error) {
    dataDB.rollback();
  }
}

/* 给所有客户端emit消息 */
function emitMessage(event: string, data: any) {
  io.sockets.emit(event, data);
}

/* 给房间所有人emit消息 */
function emitRoomMessage(room: string, event: string, data: any) {
  io.sockets.in(room).emit(event, data);
}

/**
 * 创建房间id
 * @returns 随机字符串
 */
function generateRoomId() {
  const id = utils.generateRandomString();
  const existRoom = room_list.find((item) => {
    return item.id === id;
  });
  if (!existRoom) {
    return id;
  }
  return generateRoomId();
}

/**
 * 保存日志
 * @param room_id 房间id
 * @param message 日志消息
 * @param color 日志颜色
 */
function saveLog(room_id: string, message: string, color?: 'success' | 'warning' | 'error') {
  const t = utils.getCurDateTime();
  logManager.insert(
    room_id,
    {
      ...t,
      value: message,
      color: color || ''
    },
    (res: IResponse) => {
      if (!res.result) {
        console.error('[saveLog]: ', res.message);
      } else {
        // 同步log信息
        emitMessage('addLog', {
          room_id,
          data: {
            time: t.time,
            value: message,
            color: color || ''
          }
        });
      }
    }
  );
}

function getRoomOnlineCtlDevids(room: IRoom) {
  const { devids } = room || {};
  const ac_devids = []; // 房间内在线的空调设备
  const light_devids = []; // 房间内在线的灯设备
  devids.map((item) => {
    const d = devManager.devMap.get(item);
    if (d) {
      if (d.type === 'ac-control') {
        ac_devids.push(item);
      } else if (d.type === 'light-control') {
        light_devids.push(item);
      } else if (d.type === 'light-ac-control') {
        ac_devids.push(item);
        light_devids.push(item);
      }
    }
  });
  return { ac_devids, light_devids };
}

/**
 * 初始化设备当前实时值
 * @param dev 设备信息
 */
function initDevCurrentValue(dev: ISimpleDevice) {
  switch (dev.type) {
    case 'body-sensor':
      devManager.sendDeviceInfo(dev.devid, {
        method: 'get',
        obj: ['micro_state']
      });
      break;
    case 'illu-sensor':
      devManager.sendDeviceInfo(dev.devid, {
        method: 'get',
        obj: ['illu']
      });
      break;
    case 'ac-control':
      devManager.sendDeviceInfo(dev.devid, {
        method: 'get',
        obj: ['ac']
      });
      break;
    case 'body-illu-sensor':
      devManager.sendDeviceInfo(dev.devid, {
        method: 'get',
        obj: ['micro_state']
      });
      devManager.sendDeviceInfo(dev.devid, {
        method: 'get',
        obj: ['illu']
      });
      break;
    case 'light-ac-control':
      devManager.sendDeviceInfo(dev.devid, {
        method: 'get',
        obj: ['ac']
      });
      break;
    default:
      console.error('Function initDevCurrentValue error.');
      break;
  }
}

/* 重置房间设备 */
function initRoomRealValue() {
  room_list = room_list.map((item: IRoom) => {
    roomRealValues[item.id] = {
      bodySensor: [],
      illuSensor: [],
      ac: []
    };
    item.status = false;
    return item;
  });
}

function addRoomAutoControlCount(roomId: string) {
  room_list = room_list.map((item: IRoom) => {
    if (item.id === roomId) {
      console.log('addRoomAutoControlCount true');
      item.count += 1;
    }
    return item;
  });
  console.info(room_list.find((item) => item.id === roomId));
  updateRooms();
}

app.start();
require('iosched').forever();
